<script setup lang="ts">
import { ref, computed } from 'vue'

interface Note {
  id: number
  title: string
  content: string
  createdAt: Date
  updatedAt: Date
}

interface Props {
  notes: Note[]
  currentNote: Note | null
}

interface Emits {
  (e: 'select-note', note: Note): void
  (e: 'create-note'): void
  (e: 'delete-note', noteId: number): void
  (e: 'detach-note', note: Note): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

const searchQuery = ref('')
const isDeleteDialogOpen = ref(false)
const noteToDelete = ref<Note | null>(null)
const draggedNote = ref<Note | null>(null)
const isDragging = ref(false)

const filteredNotes = computed(() => {
  if (!searchQuery.value) return props.notes
  return props.notes.filter(
    (note) =>
      note.title.toLowerCase().includes(searchQuery.value.toLowerCase()) ||
      note.content.toLowerCase().includes(searchQuery.value.toLowerCase())
  )
})

const formatDate = (date: Date): string => {
  return date.toLocaleDateString('zh-CN', {
    year: 'numeric',
    month: 'short',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit'
  })
}

const handleSelectNote = (note: Note): void => {
  if (!isDragging.value) {
    emit('select-note', note)
  }
}

const handleCreateNote = (): void => {
  emit('create-note')
}

// 测试脱出功能
const handleTestDetach = (note: Note): void => {
  console.log('测试脱出功能，note:', note.title)
  emit('detach-note', note)
}

const handleDeleteNote = (event: Event, note: Note): void => {
  event.stopPropagation()
  console.log('删除按钮被点击', note.title)
  noteToDelete.value = note
  isDeleteDialogOpen.value = true
}

const confirmDelete = (): void => {
  console.log('确认删除', noteToDelete.value?.title)
  if (noteToDelete.value) {
    emit('delete-note', noteToDelete.value.id)
  }
  isDeleteDialogOpen.value = false
  noteToDelete.value = null
}

const cancelDelete = (): void => {
  console.log('取消删除')
  isDeleteDialogOpen.value = false
  noteToDelete.value = null
}

// 拖拽事件处理
const handleDragStart = (event: DragEvent, note: Note): void => {
  if (!event.dataTransfer) return

  draggedNote.value = note
  isDragging.value = true

  // 设置拖拽数据
  event.dataTransfer.setData('application/json', JSON.stringify(note))
  event.dataTransfer.effectAllowed = 'move'

  // 添加拖拽样式
  const target = event.target as HTMLElement
  if (target) {
    target.style.opacity = '0.5'
  }

  console.log('开始拖拽note:', note.title)
}

const handleDragEnd = (event: DragEvent): void => {
  console.log('拖拽结束，清理状态')

  // 只负责清理状态，不处理脱出逻辑
  // 脱出逻辑交给 handleGlobalDrop 处理

  // 清理状态
  isDragging.value = false
  draggedNote.value = null

  // 恢复样式
  const target = event.target as HTMLElement
  if (target) {
    target.style.opacity = '1'
  }
}

// 处理note标题的拖拽
const handleNoteTitleDragStart = (event: DragEvent, note: Note): void => {
  console.log('Note 拖拽开始:', note.title)
  handleDragStart(event, note)

  // 添加全局拖拽监听器
  document.addEventListener('dragover', handleGlobalDragOver, true)
  document.addEventListener('drop', handleGlobalDrop, true)
}

const handleNoteTitleDragEnd = (event: DragEvent): void => {
  console.log('Note 拖拽结束')

  // 延迟一小段时间再清理状态，确保全局drop事件先执行
  setTimeout(() => {
    handleDragEnd(event)

    // 移除全局监听器
    document.removeEventListener('dragover', handleGlobalDragOver, true)
    document.removeEventListener('drop', handleGlobalDrop, true)
  }, 50)
}

// 全局拖拽事件处理
const handleGlobalDragOver = (event: DragEvent): void => {
  event.preventDefault()
  // 这里只需要阻止默认行为，实际检测在drop事件中进行
}

const handleGlobalDrop = (event: DragEvent): void => {
  event.preventDefault()

  console.log('全局Drop事件触发，检查脱出条件')

  if (!isDragging.value || !draggedNote.value) {
    console.log('无拖拽状态或note，跳过')
    return
  }

  const sidebarElement = document.querySelector('.sidebar-container') as HTMLElement
  if (!sidebarElement) {
    console.log('未找到侧边栏元素')
    return
  }

  const sidebarRect = sidebarElement.getBoundingClientRect()
  const isDroppedOnSidebar =
    event.clientX >= sidebarRect.left &&
    event.clientX <= sidebarRect.right &&
    event.clientY >= sidebarRect.top &&
    event.clientY <= sidebarRect.bottom

  console.log(
    '全局Drop事件，是否在侧边栏内:',
    isDroppedOnSidebar,
    '坐标:',
    event.clientX,
    event.clientY
  )

  if (!isDroppedOnSidebar) {
    console.log('拖拽到应用外部，准备脱出note:', draggedNote.value.title)
    emit('detach-note', draggedNote.value)
  } else {
    console.log('拖拽在侧边栏内部，不脱出')
  }
}
</script>

<template>
  <div class="sidebar-container" @dragover="handleGlobalDragOver" @drop="handleGlobalDrop">
    <!-- 头部 -->
    <v-card flat color="transparent" class="pa-4">
      <div class="d-flex justify-space-between align-center mb-3">
        <v-card-title class="text-h6 pa-0 text-grey-lighten-2"> Orange Note </v-card-title>
        <v-btn icon="mdi-plus" size="small" color="primary" @click="handleCreateNote"></v-btn>
      </div>

      <!-- 搜索框 -->
      <v-text-field
        v-model="searchQuery"
        placeholder="搜索笔记..."
        prepend-inner-icon="mdi-magnify"
        variant="outlined"
        density="compact"
        hide-details
        color="primary"
        class="mb-3"
      ></v-text-field>
    </v-card>

    <!-- 笔记列表 -->
    <v-list density="compact" color="transparent">
      <v-list-item
        v-for="note in filteredNotes"
        :key="note.id"
        :class="{ 'note-dragging': isDragging && draggedNote?.id === note.id }"
        :active="currentNote?.id === note.id"
        color="primary"
        @click="handleSelectNote(note)"
      >
        <div
          class="note-content-drag"
          draggable="true"
          @dragstart="handleNoteTitleDragStart($event, note)"
          @dragend="handleNoteTitleDragEnd($event)"
        >
          <v-list-item-title class="text-grey-lighten-2">
            {{ note.title || '无标题' }}
          </v-list-item-title>
          <v-list-item-subtitle class="text-grey-lighten-1 text-caption">
            {{ note.content.substring(0, 40) || '暂无内容' }}
          </v-list-item-subtitle>
          <div class="text-caption text-grey mt-1">
            {{ formatDate(note.updatedAt) }}
          </div>
        </div>

        <template #append>
          <div class="note-actions">
            <v-btn
              icon="mdi-open-in-new"
              size="x-small"
              variant="text"
              color="info"
              @click.stop="handleTestDetach(note)"
            ></v-btn>
            <v-btn
              icon="mdi-delete"
              size="x-small"
              variant="text"
              color="error"
              @click.stop="handleDeleteNote($event, note)"
            ></v-btn>
          </div>
        </template>
      </v-list-item>
    </v-list>

    <!-- 空状态 -->
    <v-card v-if="filteredNotes.length === 0" flat color="transparent" class="text-center pa-6">
      <v-icon icon="mdi-note-outline" size="48" color="grey"></v-icon>
      <v-card-text class="text-grey">
        {{ searchQuery ? '未找到匹配的笔记' : '暂无笔记' }}
      </v-card-text>
    </v-card>

    <!-- 拖拽提示 -->
    <v-card
      v-if="isDragging"
      color="primary"
      variant="tonal"
      class="ma-4 pa-3 text-center drag-hint"
    >
      <v-icon icon="mdi-drag" class="mb-2"></v-icon>
      <div class="text-body-2">拖拽到应用外部以创建新窗口</div>
    </v-card>

    <!-- 删除确认对话框 -->
    <v-dialog v-model="isDeleteDialogOpen" max-width="400">
      <v-card>
        <v-card-title class="text-h6">删除笔记</v-card-title>
        <v-card-text>
          确定要删除 "{{ noteToDelete?.title || '无标题' }}" 吗？此操作无法撤销。
        </v-card-text>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn text @click="cancelDelete">取消</v-btn>
          <v-btn color="error" @click="confirmDelete">删除</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </div>
</template>

<style scoped>
.sidebar-container {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.note-content-drag {
  flex: 1;
  cursor: grab;
  user-select: none;
  width: 100%;
}

.note-content-drag:active {
  cursor: grabbing;
}

.note-dragging {
  opacity: 0.6;
}

.note-actions {
  display: flex;
  gap: 4px;
  opacity: 0;
  transition: opacity 0.2s;
}

.v-list-item:hover .note-actions {
  opacity: 1;
}

.drag-hint {
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 0.8;
  }
  50% {
    opacity: 0.5;
  }
}
</style>
